#include"pro_pool.h"
#define MAX_SIZE 6
#define FUN_SIZE 5

typedef void (*func)();


void loading_function(std::vector<func>& funmap)
{
      funmap.push_back(fun_1);
      funmap.push_back(fun_2);
      funmap.push_back(fun_3);
      funmap.push_back(fun_4);
      funmap.push_back(fun_5);
}


void create_child_process(std::vector<process_child> &children, std::vector<func>& funmap)
{
    for (int i = 0; i < MAX_SIZE; i++)
   {
        int fds[2];
        if (pipe(fds) == -1) perror("make pipe fail"), exit(0);
        
        pid_t id = fork();
        if (id  == -1) perror("fork fail"), exit(0);

        if (id == 0)
        {
            int order = -1;
            close(fds[1]);
            while(true)
            {
                int n = read(fds[0], &order, sizeof(order));
                if (n == -1) exit(0);

                if (order < FUN_SIZE) {
                    funmap[order]();
                }
                else perror("execute fail");
            }           
        }
        
        close(fds[0]);
        children.push_back(process_child(id, fds[1]));   

   }
}


int main()
{
   std::vector<func> funmap;
   std::vector<process_child> children;
   srand((unsigned long)time(nullptr) ^  0x171237 ^ rand() % 1234);
   
   //create execution function
   loading_function(funmap);

   //create child process to execute command
   create_child_process(children, funmap); 
 
   //communicate with child and order command
   while(true)
   {
      int com_obj = rand() % MAX_SIZE;
      int exe_fun = rand() % FUN_SIZE;
      
      std::cout<< "process: "<< com_obj<< " id: " <<children[com_obj]._id << std::endl; 
      int n = write(children[com_obj]._writeid, &exe_fun, sizeof(exe_fun));
      if (n != sizeof(int)) perror("write fail"), exit(0);
      sleep(2);

   }

   //release child_process
   for (int i = 0; i < MAX_SIZE; i++)
   {
       close(children[i]._writeid);
   }

    return 0;
}